<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>动态路由匹配</title>
    <!-- <script src="../vue.js"></script> -->
    <script src="https://unpkg.com/vue@2.7.7/dist/vue.js"></script>
    <script src="https://unpkg.com/vue-router@3.6.5/dist/vue-router.js"></script>
  </head>
  <body>
    <!-- 1 响应路由参数的变化 -->
    <!-- 2捕获所有路由或 404 Not found 路由 -->
    <!-- 3 高级匹配模式 -->
    <!-- 4 匹配优先级 -->
    <div id="app1" style="border: 1px dashed red;margin-bottom: 2px;">
      <p>
        <!-- 使用 router-link 组件来导航. -->
        <!-- 通过传入 `to` 属性指定链接. -->
        <!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
        <router-link to="/user/001">go to foo1</router-link>
        <router-link to="/user/002">go to bar1</router-link>
        <router-link to="/user/zhangsan">go to bar2</router-link>
        <router-link to="/user/lisi/post/post003">go to bar3</router-link>
      </p>
      <!-- 路由出口 -->
      <!-- 路由匹配到的组件将渲染在这里 -->
      <router-view></router-view>
    </div>
    
    <div id="app2" style="border: 1px dashed blue;margin-bottom: 2px;">
      <p>
        <router-link to="/user/003">go to 003</router-link>
        <router-link to="/user/004">go to 004</router-link>
      </p>
      <router-view></router-view>
    </div>
    
    <div id="app3" style="border: 1px dashed red;margin-bottom: 2px;">
      <p>
        <router-link to="/user/003">go to 003</router-link>
        <router-link to="/user/004">go to 004</router-link>
      </p>
      <router-view></router-view>
    </div>
    
    
    <script type="text/javascript">
      const User = {template: '<div>User: {{$route.params.id}}</div>'}
      const User2 = {template: '<div>User: <br />username: {{$route.params.username}}<br />post_id: {{$route.params.post_id}}</div>'}
      const router = new VueRouter({
        routes: [
          // 一个“路径参数”使用冒号 : 标记。当匹配到一个路由时，参数值会被设置到 this.$route.params，可以在每个组件内使用。于是，我们可以更新 User 的模板，输出当前用户的 ID：
          {path: '/user/:id', component: User},
          // 你可以在一个路由中设置多段“路径参数”，对应的值都会设置到 $route.params 中。例如：
          {path: '/user/:username/post/:post_id', component: User2}
          // 除了 $route.params 外，$route 对象还提供了其它有用的信息，例如，$route.query (如果 URL 中有查询参数)、$route.hash 等等。你可以查看 API 文档 的详细说明。
        ]
      })
      
      const app1 = new Vue({
        // el: '#app1', // 这种写法也行
        router
      }).$mount('#app1')

      // 1 响应路由参数的变化
      const User3 = {
        template: '<div>User: {{$route.params.id}}</div>',
        // 复用组件时，想对路由参数的变化作出响应的话，你可以简单地 watch (监测变化) $route 对象：
        watch: {
          $route(to, from) {
            // 对路由变化作出响应...
            console.log('watch::: from: ' + from.path + '; to: ' + to.path)
          }
        },
        // 或者使用 2.2 中引入的 beforeRouteUpdate 导航守卫：
        beforeRouteUpdate(to, from, next) {
          // react to route changes...
          console.log('beforeRouteUpdate::: from: ' + from.path + '; to: ' + to.path)
          // don't forget to call next()，因为必须调用了next()之后，路径才会真正变化！
          next()
        }
      }
      
      const router2 = new VueRouter({
        routes: [
          {path: '/user/:id', component: User3}
        ]
      })
      
      new Vue({
        el: '#app2',
        router: router2
      })
      
      // 2捕获所有路由或 404 Not found 路由
      //   常规参数只会匹配被 / 分隔的 URL 片段中的字符。如果想匹配任意路径，我们可以使用通配符 (*)：
      const router3 = new VueRouter({
        routes: [
          // 会匹配所有路径
          {path: '*'},
          // 会匹配以 `/user-` 开头的任意路径
          {path: '/user-*'}
        ]
      })
      
      var vm3 = new Vue({
        el: '#app3',
        router: router3
      })
      //   当使用一个通配符时，$route.params 内会自动添加一个名为 pathMatch 参数。它包含了 URL 通过通配符被匹配的部分
      vm3.$router.push('/aaa')
      vm3.$route.params.pathMatch // output: aaa
      vm3.$router.push('/user-bbb')
      vm3.$route.params.pathMatch // output: bbb

      // 3 高级匹配模式
      //   vue-router 使用 path-to-regexp (opens new window)作为路径匹配引擎，所以支持很多高级的匹配模式，例如：可选的动态路径参数、匹配零个或多个、一个或多个，甚至是自定义正则匹配。查看它的文档 (opens new window)学习高阶的路径匹配，还有这个例子  (opens new window)展示 vue-router 怎么使用这类匹配。
      // 4 匹配优先级
      //   有时候，同一个路径可以匹配多个路由，此时，匹配的优先级就按照路由的定义顺序：路由定义得越早，优先级就越高。

    </script>
  </body>
</html>